#include "Test.Font.h"

#undef  APP_NAME
#define APP_NAME	TestSensorAccel
#undef  APP_BASE
#define APP_BASE	TestFont


class APP_NAME : public APP_BASE
{
	typedef SHARED_POINTER_TYPE( APP_NAME )		TestSensorAccelPtr;

protected:
	vec3	accel;
	float	accelTime;
	float	accelCounter;
	float	timeDelta;
	vec2	pos;
	vec2	vel;
	float	friction;

	SysEvent::time_t	lastTime;


public:
	APP_NAME (IPlatform *platform, EDevice::type deviceType) :
		APP_BASE( platform, deviceType ), accelTime(0.0f), timeDelta(0.0f),
		accelCounter(0.0f), friction(0.3f)
	{
		DESCTOP_ONLY( friction = 0.001f; )

		ESS()->GetEventSystem()->AttachEventListener(
			DelegateBuilder::Create( TestSensorAccelPtr(this), &APP_NAME::_OnAccel ),	ESystemEvent::ACCEL );
	}


	~APP_NAME ()
	{
		ESS()->GetEventSystem()->DetachEventListener(
			DelegateBuilder::Create( TestSensorAccelPtr(this), &APP_NAME::_OnAccel ),	ESystemEvent::ACCEL );
	}


	void Update (float dt) override
	{
		TestApp::Update( dt );

		ViewportPtr	vp = ESS()->GetGraphicsEngine()->GetViewport();

		vp->Apply();
		ESS()->GetGLStateManager()->ClearColor( color4f( 0.0f ) );

		pos = Clamp( pos, vec2(-1.0f), vec2(1.0f) );

		ESS()->GetGraphicsEngine()->GetRender2D().DrawCircle( material, pos, 0.1f, 12, color4u(255), true );

		pos += vel * dt;
		vel -= vel * friction;

		string	str;
		vec3	a = accelCounter < 1.0f ? vec3() : accel / accelCounter;
		float	t = accelCounter < 1.0f ? 0.0f : timeDelta / accelCounter;

		str << string().FormatF( a.x, StringFormatF().Fmt(0,2) ) << "\n"
			<< string().FormatF( a.y, StringFormatF().Fmt(0,2) ) << "\n"
			<< string().FormatF( a.z, StringFormatF().Fmt(0,2) ) << "\ndt "
			<< string().FormatF(   t, StringFormatF().Fmt(0,4) );

		fontBatch.Draw( vec2(0.0f), str );

		batch.Flush();
		batch.Clear();
		
		ESS()->GetGraphicsEngine()->SwapBuffers();
	}
	

	void OnEnter () override
	{
		APP_BASE::OnEnter();

		GetPlatform()->EnableSensor( ESensor::ACCELEROMETER );
	}


	void OnAccel (SysEvent::time_t time, const vec3 &accel)
	{
		float	dt = (float) (time - lastTime).ToDouble().GetSec();

		MOBILE_ONLY(
		if ( dt > 0.5f )
		{
			lastTime = time;
			return;
		}
		)

		if ( accelTime > 1.0f )
		{
			this->accel	 = vec3();
			accelTime	 = 0.0f;
			accelCounter = 0.0f;
			timeDelta	 = 0.0f;
		}

		accelCounter++;
		accelTime += dt;
		timeDelta += dt;

		this->accel += accel;

		vel += accel.xy() * -dt;

		lastTime = time;
	}
	

	void _OnAccel (const SysEvent &ev)
	{
		OnAccel( ev.timestamp, vec3( ev.accel.x, ev.accel.y, ev.accel.z ) );
	}
};